/*
 * @Author: weidewei
 * @Date: 2025-11-06 15:10:45
 * @LastEditors: weidewei
 * @LastEditTime: 2025-11-07 17:49:20
 * @Description:
 * @FilePath: \2025-front-face\js常见手写题\promise.js
 */
/**
 * 1. 实现状态的变化
 * 2. 创建then函数
 * 3. 生成执行队列
 * 4. 遍历执行队列
 * 5. catch和finally方法的实现 
 *
 */
/**
 * 运行一个微队列任务
 * @param {Function} callback
 */
function runMicroTask(callback) {
  if (process && process.nextTick) {
    process.nextTick(callback);
  } else if (MutationObserver) {
    const div = document.createElement('div');
    const observer = new MutationObserver(callback);
    observer.observe(div, {
      childList: true, // 观察元素的变化
    });
    div.innerHTML = '1';
  } else {
    setTimeout(callback, 0);
  }
}

/**
 * 
 * @param {any} obj 判断一个对象是不是promise
 */

function isPromise(obj) {
 return !!(obj && typeof obj === 'object' && typeof obj.then === 'function');
}

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
// class默认开启严格模式，严格模式下的this指向undefined
class myPromise {
  constructor(executor) {
    this._state = PENDING;
    this._value = undefined;
    this._handlers = [];
    try {
      executor(this._resolve.bind(this), this._reject.bind(this)); // 这里要绑定this,不然this直接调用会变成undefined
    } catch (err) {
      this._reject(err);
      console.log(err);
    }
  }
  /**
   * 向处理队列中添加一个函数
   * @param {Function} executor 要添加的函数
   * @param {String} state 该函数在什么状态下执行
   * @param {Function} resolve 让then函数返回的promise成功
   * @param {Function} reject 让then函数返回的promise失败
   */
  _pushHandler(executor,state,resolve,reject) {
    this._handlers.push({
      executor,
      state,
      resolve,
      reject
    })
  }

  /**
   * 根据实际情况 执行队列
   *
   */
  _runHandlers() {
    if(this._state === PENDING) return;
    // console.log(`处理${this._handlers.length}个函数`);
    // console.log(this._handlers);
    while(this._handlers[0]) {
      const handler = this._handlers[0];
      this._runOneHandler(handler);
      this._handlers.shift();
    }
    
  }

  /**
   * 一次只执行一个handler
   * @param {Object} handler 
   */
  _runOneHandler({executor,state,resolve,reject}) {
    // 放到微队列里面执行
    runMicroTask(()=>{
      // 状态不一致，不处理
      if(state !== this._state) return;
      // console.log('this._state',this._state);
      // console.log('handler',handler);
      if(typeof executor !== 'function') {
        // 传递后续处理并非一个函数，要进行状态穿透
        this._state === FULFILLED ? resolve(this._value) : reject(this._value); 
        return;
      }
      try{
        const result = executor(this._value);
        if(isPromise(result)) {
          result.then(resolve,reject);
        }else {
          resolve(result);
        }
      }catch(err){
        reject(err);
      }

    })
  }
  

  /**
   *
   * @param {Function} onFulFilled 成功执行的回调
   * @param {Function} onRejected  失败执行的回调
   * @returns
   */
  then(onFulFilled, onRejected) {
    return new myPromise((resolve, reject) => {
      this._pushHandler(onFulFilled,FULFILLED,resolve,reject);
      this._pushHandler(onRejected,REJECTED,resolve,reject);
      this._runHandlers();
    });
  }

  _resolve(data) {
    this._setState(FULFILLED, data);
  }

  _reject(reson) {
    this._setState(REJECTED, reson);
  }

  /**
   * 
   * @param {Function} onRejected 失败的回调
   * @returns 
   */
  catch(onRejected) {
    return this.then(null,onRejected);
  }

  /**
   * 不管成功还是失败，都会执行回调
   * @param {Function} onSettled 
   */
  finally(onSettled) {
    // 这样写会造成下一个promise值穿透的问题
    // return this.then(onSettled,onSettled);

    return this.then((data)=>{
      onSettled();
      return data;
    },(reason)=>{
      onSettled();
      throw reason;
    })
  }
  /**
   * 返回的一个已完成的promise
   * 特殊情况：
   * 1.传递的data本身是一个ES6 promise对象
   * 2.传递的data是一个promiseLike（符合Promise A+规范）
   * @param {Function} data 
   */
  static resolve(data) {
    if(data instanceof myPromise) {
      return data;
    }
    return new myPromise((resolve,reject)=>{
      if(isPromise(data)) {
        data.then(resolve,reject);
      }else {
        resolve(data);
      }
    })
  }

  /**
   * 得到一个被拒绝的promise
   * @param {Function} reason 
   */
  static reject(reason) {
    return new myPromise((resolve,reject)=>{
      reject(reason);
    })
  }

  /**
   * 得到一个新的promise，该promise的状态取决于promises的执行，
   * promises是一个迭代器，包含多个promise，全部promise成功，则返回成功，数据为所有promise成功的数据
   * 并且顺序是按照传入的顺序排列，只要有一个promise失败，则返回的promise失败，原因是第一个promise失败的原因
   * @param {Iterator} promises 是一个迭代器
   */
  static all(promises) {
    return new myPromise((resolve,reject)=>{
      const results = [];
      // promise的计数
      let count = 0;
      // 已完成的数量
      let fulfilledCount = 0;
      for(const p of promises) {
        let index = count;
        count++;
        myPromise.resolve(p).then((data)=>{
          fulfilledCount++;
          console.log('index',index);
          // 不能用push的方式，否则顺序就不对了
          // results.push(data);
          results[index] = data;
          if(fulfilledCount === count) {
            // 当前是最后一个promise完成了
            resolve(results);
          }
        },reject);
      }
      console.log(count);
    })
  }

  /**
   * 
   * @param {Iterator} promises 
   */
  static allSettled(promises) {
    const ps = [];
    for(const prom of promises) {
      ps.push(myPromise.resolve(prom).then(value=>({
        status: FULFILLED,
        value 
      }),reason=>({
        status: REJECTED,
        reason
      })))
    }
    return myPromise.all(ps);
  }

  /**
   * 返回的promise与第一个有结果的一致
   * @param {Iterator} promise 
   */
  static race(promises) {
    return new myPromise((resolve,reject)=>{
      for (const p of promises) {
          myPromise.resolve(p).then(resolve,reject)
      }
    })
  }
  _setState(state, value) {
    if (this._state !== PENDING) return;
    this._state = state;
    this._value = value;
    // 状态变化执行队列
    this._runHandlers();
  }
}
// console.log(1);
// setTimeout(() => {
//   console.log(888);
// }, 1000);
// runMicroTask(() => {
//   console.log(2);
// });

// const p = new myPromise((resolve,reject)=>{
//     resolve(1)
// });
// const p2 = p.then(data=>{
//   console.log('resovedata',data);
// }).catch(err=>{
//   console.log(err);
// }).finally((vv)=>{
//   console.log('vv',vv);
//   console.log('最后的输出');
//   throw new Error('error');
// }).then(res=>{
//   console.log('res',res);
// }).catch(err1=>{
//   console.log('err1',err1);
// });

// 静态方法测试
const p1 =  new myPromise((resolve,reject)=>{
  setTimeout(() => {
    reject(1);
  }, 3050);
});
const p2 =  new myPromise((resolve,reject)=>{
  setTimeout(() => {
    resolve(2);
  }, 1550);
});
const p3 = new myPromise((resolve,reject)=>{
  setTimeout(() => {
    resolve(3);
  }, 2000);
});
const allp =  myPromise.race([p1,p2,p3]).then(res=>{
  console.log('成功',res);
}).catch(err=>{
  console.log('err',err);
});



